package com.entrogy.controller;

import com.Sinewecology.config.ConfigParams;
import com.entrogy.bean.*;
import com.entrogy.dao.MessageMapper;
import com.entrogy.dao.WeixinMenuMapper;
import com.entrogy.service.*;
import com.entrogy.utils.ApiReturnUtil;
import com.entrogy.utils.HttpUtils;
import com.entrogy.utils.JsonUtils;
import com.entrogy.utils.RedisUtil;
import com.entrogy.utils.constants.Constants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.ibatis.annotations.Param;
import org.omg.CORBA.UserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import sun.rmi.runtime.Log;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xlr
 * @date 2019-6-28
 * @description 微信登录及其首页初始化
 *  第一步：调用getSessionKey 返回openid和微信表里头自增的那个id
 *  第二步：authlogin（第二次登录的时候可以查询到用户类型）
 *  第三步：调用userLogin 获取短信验证码，在第一次登录的时候用到
 */
@Api(description = "微信登录及其首页初始化模块")
@RestController
@RequestMapping(value = "/weixin")
public class WeixinLoginController {


    private static final Logger logger = LoggerFactory.getLogger(WeixinLoginController.class);
    @Value("${show.image.url}")
    private String showImage;

    @Autowired
    private WeixinService weixinService;
    @Autowired
    private UserService userService;
    @Autowired
    private ParentService parentService;
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private SchoolService schoolService;
    @Autowired
    private WeixinMenuMapper weixinMenuMapper;
    @Autowired
    private PositionService positionService;

    private RedisUtil redisUtil = new RedisUtil();
    /**
     *1.得到手机号 2.查询数据库，看是否是系统用户（老师或者家长），否则就是普通访客如果是访客则新增其电话号码
     * 3.发送验证码，返回验证码、用户类型和用户id（即我们平台统一的ID）,并将用户id保存到session中
     */
    @ApiOperation(value = "得到手机号码，发送验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "电话号码",name = "phone",dataType = "String",paramType = "query",required = true),
            @ApiImplicitParam(value = "用户的微信标识ID",name = "id",dataType = "String",paramType = "query",required = true)
    })
    @RequestMapping(value = "userlogin",method = RequestMethod.POST)
    public Map<String,Object> userLogin(HttpServletRequest request,String phone, String id){
        logger.info("验证码:" + phone + " " + id);
        Map<String,Object> map = weixinService.sendVerifycode(phone, id);
        if(map.size()==0){//验证失败
            return ApiReturnUtil.error("对不起,登录验证失败");
        }
        if (map.containsKey("teacherPhone")){
            Map<String, Object> resultMap = ApiReturnUtil.error("对不起,该账号正在审核中");
            resultMap.put("teacherPhone", map.get("teacherPhone"));
            resultMap.put("changeType", map.get("changeType"));
            return resultMap;
        }
        if (map.containsKey("weixinPhoneErrorMsg")){
            return ApiReturnUtil.error((String) map.get("weixinPhoneErrorMsg"));
        }
        if(map.containsKey("isVisitor")){
            return ApiReturnUtil.error((String) map.get("isVisitor"));
        }
        request.getSession().setAttribute("uid", map.get("uid"));//用户ID 即我们平台统一的ID
        request.getSession().setAttribute("phone", phone);
        map.remove("uid");
        return ApiReturnUtil.success("验证成功哟",map);
    }

    /**
     * 获取session_key
     * 返回openid和微信表里头自增的那个id
     */
    @ApiOperation(value = " 获取session_key返回openid和微信表里头自增的那个id")
    @RequestMapping(value = "getsessionkey",method = RequestMethod.GET)
    public Map<String,Object> getSessionKey(@RequestParam("code") String code, @RequestParam(value = "identityType",required = false) Integer identityType){
        // 小程序appid和appsecret
        String appid = ConfigParams.APPID_littleProgram;
        String appsecret = ConfigParams.APPSECRET_littleProgram;
        Map<String,Object> returnMap = new HashMap<>();
        String msg = getWeixinUserData(code, appid, appsecret); //获取unionid
        // 解析得到的string
        if (msg != null) {
            // jsonObject装有openid和session_key
            JSONObject jsonObject = JSONObject.fromObject(msg);
            if (jsonObject.getString("openid") != null && jsonObject.containsKey("unionid")) {
                // 判断该openid是否已在数据库中
                Map<String, Object> map = weixinService.insertOpenidandUnionid(jsonObject.getString("openid"),
                        jsonObject.getString("unionid"), code, identityType);
                // 将id存储到session中
                // request.getSession().setAttribute("id", response_json.getString("id"));
                if (map.size() == 0) {
                    returnMap.put("code", 0);
                    returnMap.put("msg", "网络异常");
                    returnMap.put("resultmsg", map);
                    return returnMap;
                }
                returnMap.put("code", 1);
                returnMap.put("msg", "ok");
//                returnMap.put("openid", jsonObject.getString("openid"));
//                returnMap.put("sessionkey", jsonObject.getString("session_key"));
                returnMap.put("resultmsg", map);
                return returnMap;
            }
            // 如果没有关注公众号，允许进入到下一步，在数据库中暂时不插入unionid
            else if (jsonObject.getString("openid") != null && !jsonObject.containsKey("unionid")) {
                Map<String, Object> map = weixinService.insertOpenid(jsonObject.getString("openid"));
                if (map.size() == 0) {
                    returnMap.put("code", 0);
                    returnMap.put("msg", "网络异常");
                    returnMap.put("resultmsg", map);
                    return returnMap;
                }
                returnMap.put("code", 1);
                returnMap.put("msg", "ok");
                returnMap.put("openid", jsonObject.getString("openid"));
//                returnMap.put("sessionkey", jsonObject.getString("session_key"));
                returnMap.put("resultmsg", map);
                return returnMap;
//                returnMap.put("code", 0);
//                returnMap.put("msg", "请先关注《脸卡通校园公众号》才能使用小程序！");
//                return returnMap;
            } else {
                returnMap.put("code", 0);
                returnMap.put("msg", "登录错误");
                return returnMap;
            }
        }
        return returnMap;
    }

    /**
     * 用户验证登录,返回登录信息，如果第一次登录，则没有uid和type
     */
    @ApiOperation(value = "用户验证登录,返回登录信息，如果第一次登录，则没有uid和type")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id",dataType = "String",paramType = "query",required = true,value = "weixin_information中的id"),
            @ApiImplicitParam(name = "nickName",dataType = "String",paramType = "query",required = true,value = "昵称"),
            @ApiImplicitParam(name = "headUrl",dataType = "String",paramType = "query",required = true,value = "微信头像url")
    })
    @RequestMapping(value = "authlogin",method = RequestMethod.POST)
    public Map<String,Object> authLogin(String id,String nickName,String headUrl) {
        logger.info("authlogin:" + id + " " + nickName);
        // 用户登录,返回登录信息，如果第一次登录，则没有uid和type
        try {
            Map<String,Object> map = weixinService.loginWeixin(id, nickName, headUrl);
            return ApiReturnUtil.success("验证成功",map);
        } catch (Exception e) {
            logger.error("用户authlogin验证失败authlogin:" + id + " " + nickName + "" + headUrl+e.getMessage());
            return ApiReturnUtil.error("验证失败，请重新登录！");
        }
    }
    /*
     * 首页显示 显示主要内容： 1.轮播图 2.按钮 3.通知
     */
    @ApiOperation(value = "首页显示 显示主要内容： 1.轮播图 2.按钮 3.通知")
    @ApiImplicitParam(name="uid",value = "用户ID即平台教师/家长/访客的ID",dataType = "String",paramType = "query",required = true)
    @RequestMapping(value = "firstpage",method = RequestMethod.GET)
    public Map<String,Object> firstPage(String uid){
        Map<String,Object> returnMap = new HashMap<>();
        UserEntity userEntity = null;
        Integer schoolCode = null;
        // 轮播图，轮播图的url写在配置文件里面
        // 根据uid插入手机号码到数据库
        if (!uid.startsWith("2")) { //不是访客进来 判断家长和老师的ID是否为空 如果为空则插入电话号码
            try {
                weixinService.insertPhone(uid);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("firstPage insertPhone(根据uid去微信表里边查询电话号码没有查到):uid为" + uid+e.getMessage());
                return ApiReturnUtil.error("网络异常");
            }
        }
        try {
            List<BannerEntity> picurl =  null;
            if(uid.startsWith("1")){
                 userEntity = userService.getUserByUid(uid);
                if(userEntity != null){
                    picurl = schoolService.getBanner(userEntity.getSchoolCode());
                }
            }else if(uid.startsWith("3")){
                 schoolCode = parentService.getSchoolCodeByParentId(uid);
                if(schoolCode != null){
                    picurl = schoolService.getBanner(schoolCode);
                }
            }
            // 轮播图个数
            int count = picurl != null ? picurl.size():0;
            List list = new ArrayList();
            for (int i = 0; i < count; i++) {
                Map<String,Object> picMap = new HashMap<>();
                picMap.put("id", i + 20 + "");
                picMap.put("sort", i + 1 + "");
                picMap.put("photo", picurl.get(i).getImgUrl());
                list.add(picMap);
            }
            returnMap.put("showImage",showImage);
            returnMap.put("ggtop",list);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("firstPage getPic error:" + uid+e.getMessage());
            return ApiReturnUtil.error("网络异常");
        }
        // 根据uid区别家长还是老师,家长老师可以看到的按钮与通知不一样
        Boolean flag = weixinService.haveUnionid(uid);
        // 访客
        if (uid.startsWith("2") || !flag) {
            try {
                List<WeixinMenuEntity> weixinMenuEntities = (List<WeixinMenuEntity>) redisUtil.get(Constants.VISITOR_MENU);
                if(weixinMenuEntities == null || weixinMenuEntities.size()==0){
                    weixinMenuEntities = weixinMenuMapper.getWeixinMenuListByType("4",schoolCode.toString());
                }
                List list = new ArrayList();
                for (int i = 0; i < weixinMenuEntities.size(); i++) {
                    Map<String,Object> picMap = new HashMap<>();
                    picMap.put("id", i + 2 + "");
                    picMap.put("sort", i + 1 + "");
                    picMap.put("name", weixinMenuEntities.get(i).getMenuName());
                    picMap.put("url", weixinMenuEntities.get(i).getPathUrl());
                    list.add(picMap);
                }
                returnMap.put("category",list);
                // 获取通知信息
                JSONObject jsonObject = weixinService.getMessageforVisitor();
                JSONArray jsonArray = new JSONArray();
                jsonArray.add(jsonObject);
                // 返回给前端
                returnMap.put("code", 1);
                returnMap.put("msg", "ok");
                returnMap.put("title", "访客");
                returnMap.put("notice", jsonArray);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("firstPage visitor getPic getMessage error:" + uid+e.getMessage());
                returnMap.put("code",0);
                returnMap.put("msg","网络异常");
                return returnMap;
            }
        }
        // 家长 按钮信息获取
        else if (uid.startsWith("3") && flag) {
            try {
                // 获取菜单按钮
                List<WeixinMenuEntity> weixinMenuEntities = (List<WeixinMenuEntity>) redisUtil.get(Constants.PARENT_MENU+"_"+schoolCode);
                if(weixinMenuEntities == null || weixinMenuEntities.size()==0){
                    weixinMenuEntities = weixinMenuMapper.getWeixinMenuListByType("1",schoolCode.toString());
                }
                List list = new ArrayList();
                for (int i = 0; i < weixinMenuEntities.size(); i++) {
                    Map<String,Object> picMap = new HashMap<>();
                    picMap.put("id", i + 2 + "");
                    picMap.put("sort", i + 1 + "");
                    picMap.put("name", weixinMenuEntities.get(i).getMenuName());
                    picMap.put("url", weixinMenuEntities.get(i).getPathUrl());
                    list.add(picMap);
                }
                returnMap.put("category",list);
                // 根据用户ID获取通知信息
                JSONArray notice = weixinService.getMessage(uid, 1, 10);
                // 返回给前端
                String parentName = parentService.getParentName(uid);
                returnMap.put("code", 1);
                returnMap.put("msg", "ok");
                returnMap.put("title", "脸卡通" + parentName + ", 您好！");
                returnMap.put("notice", notice);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("firstPage user getPic getMessage error:" + e.getMessage());
                returnMap.put("code", 0);
                returnMap.put("msg", "网络异常");
                return returnMap;
            }
            // 以下是老师登陆的首页显示
        } else if (uid.startsWith("1") && flag) {
            schoolCode = userEntity.getSchoolCode();
            List<Integer> positions = positionService.listPositionId(uid);
            if (positions.isEmpty()){
                logger.error("教师" + userEntity.getName()+ "用户id" + uid + "职位设置不正确！");
                returnMap.put("code", 0);
                returnMap.put("msg", "您在系统中暂未设置职位，请联系管理员修改职位后再登录使用！");
                return returnMap;
            }
            try {
                // 获取按钮信息 德育处-----5，生活老师----3，家长---1，保安-----6，普通老师---2，访客----4
                List<WeixinMenuEntity> weixinMenuEntities = new ArrayList<>();
                List<WeixinMenuEntity> deyuchuMenu = new ArrayList<>();
                List<WeixinMenuEntity> securityMenu = new ArrayList<>();
                List<WeixinMenuEntity> generalMenu = new ArrayList<>();
                if (positions.contains(8) || positions.contains(23) || positions.contains(24)) {//后勤主任，生活老师，其他，其他
                    weixinMenuEntities = (List<WeixinMenuEntity>) redisUtil.get(Constants.LIFE_TEACHER_MENU+"_"+schoolCode);//-----生活老师菜单
                    if(weixinMenuEntities == null || weixinMenuEntities.isEmpty()){
                        weixinMenuEntities = weixinMenuMapper.getWeixinMenuListByType("3",schoolCode.toString());
                    }
                }
                if (positions.contains(1) || positions.contains(2) || positions.contains(3) ||positions.contains(5) || positions.contains(6) || positions.contains(9) || positions.contains(10)
                        || positions.contains(12) || positions.contains(13) || positions.contains(15) || positions.contains(16) ) {//校长，教务处主任，第一个其他
                    if(weixinMenuEntities.isEmpty()){
                        weixinMenuEntities = (List<WeixinMenuEntity>) redisUtil.get(Constants.DE_YU_CHU_MENU+"_"+schoolCode); //-----德育处权限菜单即所有菜单
                        if(weixinMenuEntities == null || weixinMenuEntities.isEmpty()){
                            weixinMenuEntities = weixinMenuMapper.getWeixinMenuListByType("5",schoolCode.toString());
                        }
                    }else {
                        deyuchuMenu = (List<WeixinMenuEntity>) redisUtil.get(Constants.DE_YU_CHU_MENU+"_"+schoolCode); //-----德育处权限菜单即所有菜单
                        if(deyuchuMenu == null || deyuchuMenu.isEmpty()){
                            deyuchuMenu = weixinMenuMapper.getWeixinMenuListByType("5",schoolCode.toString());
                        }
                        for (WeixinMenuEntity menu : deyuchuMenu){
                            weixinMenuEntities.add(menu);
                        }
                    }

                }
                if (positions.contains(22)) {//保安
                    if(weixinMenuEntities.isEmpty()){
                        weixinMenuEntities = (List<WeixinMenuEntity>) redisUtil.get(Constants.SECRITY_MENU+"_"+schoolCode);//-----保安菜单
                        if(weixinMenuEntities == null || weixinMenuEntities.isEmpty()){
                            weixinMenuEntities = weixinMenuMapper.getWeixinMenuListByType("6",schoolCode.toString());
                        }
                    }else{
                        securityMenu = (List<WeixinMenuEntity>) redisUtil.get(Constants.SECRITY_MENU+"_"+schoolCode);//-----保安菜单
                        if(securityMenu == null || securityMenu.isEmpty()){
                            securityMenu = weixinMenuMapper.getWeixinMenuListByType("6",schoolCode.toString());
                        }
                        for (WeixinMenuEntity menu : securityMenu){
                            weixinMenuEntities.add(menu);
                        }
                    }
                }
                if(positions.contains(4) || positions.contains(7) || positions.contains(11) || positions.contains(14) || positions.contains(17) || positions.contains(18) || positions.contains(19) || positions.contains(20) || positions.contains(21) || positions.contains(25)) {//普通老师
                    if(weixinMenuEntities.isEmpty()){
                        weixinMenuEntities = (List<WeixinMenuEntity>) redisUtil.get(Constants.TEACHER_MENU+"_"+schoolCode);//-----普通老师菜单
                        if(weixinMenuEntities == null || weixinMenuEntities.isEmpty()){
                            weixinMenuEntities = weixinMenuMapper.getWeixinMenuListByType("2",schoolCode.toString());
                        }
                    }else{
                        generalMenu = (List<WeixinMenuEntity>) redisUtil.get(Constants.TEACHER_MENU+"_"+schoolCode);//-----普通老师菜单
                        if(generalMenu == null || generalMenu.isEmpty()){
                            generalMenu = weixinMenuMapper.getWeixinMenuListByType("2",schoolCode.toString());
                        }
                        for (WeixinMenuEntity menu : generalMenu){
                            weixinMenuEntities.add(menu);
                        }
                    }
                }
                if(!weixinMenuEntities.isEmpty()){
                    weixinMenuEntities = weixinMenuEntities.stream().distinct().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getMenuName() + ";" + o.getPathUrl()))), ArrayList::new));
                }
                Collections.sort(weixinMenuEntities, new Comparator<WeixinMenuEntity>() {
                    @Override
                    public int compare(WeixinMenuEntity menu1, WeixinMenuEntity menu2) {
                        //升序
                        return menu1.getOrderNum() - menu2.getOrderNum();
                    }
                });
                List list = new ArrayList();
                for (int i = 0; i < weixinMenuEntities.size(); i++) {
                    Map<String,Object> picMap = new HashMap<>();
                    picMap.put("id", i + 2 + "");
                    picMap.put("sort", i + 1 + "");
                    picMap.put("name", weixinMenuEntities.get(i).getMenuName());
                    picMap.put("url", weixinMenuEntities.get(i).getPathUrl());
                    list.add(picMap);
                }
                returnMap.put("category",list);
                // 获取通知信息
                JSONArray jsonArray = weixinService.getMessage(uid, 1, 10);
                // 返回给前端
                returnMap.put("code", 1);
                returnMap.put("msg", "ok");
                returnMap.put("title", "“熵熵”脸卡通" + userEntity.getName() + "老师，您好！");
                returnMap.put("notice", jsonArray);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("firstPage User getPic getMessage error:" + uid+e.getMessage());
                returnMap.put("code", 0);
                returnMap.put("msg", "网络异常");
                return returnMap;
            }
        }
        return returnMap;
    }

    @ApiOperation(value = "获取消息列表的首页")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "用户ID",value = "uid",paramType = "query",dataType = "String",required = true),
            @ApiImplicitParam(name = "用户的请求来源 1--来自消息列表  否则是首页的更新请求",value = "uid",paramType = "query",dataType = "String",required = true)
    })
    @RequestMapping(value = "noticelist",method = RequestMethod.GET)
    public Map<String,Object> noticeList(String uid,String from) {
        Map<String,Object> returnMap = new HashMap<>();
        Boolean flag = weixinService.haveUnionid(uid);
        if (uid.startsWith("2") || !flag) {
            try {
                List list = new ArrayList();
                JSONObject jsonObject = weixinService.getMessageforVisitor();
                int length = weixinService.getMessageLength(uid);// notice.size();
                returnMap.put("code", 1);
                returnMap.put("msg", "ok");
                returnMap.put("total", length);
                returnMap.put("pagenum", jsonObject.size());
                returnMap.put("eachpage", 10);
                list.add(jsonObject);
                returnMap.put("notice",list);
                return returnMap;
            } catch (Exception e) {
                logger.error("noticelsit error:" + uid + " " + from+"===>>"+e.getMessage());
                returnMap.put("code", 0);
                returnMap.put("msg", "网络异常");
                return returnMap;
            }
        }
        // 表示来自消息列表
        if (from.equals("1") && flag) {
            try {
                JSONArray jsonArray = weixinService.getMessage(uid, 1, 10);
                int length = weixinService.getMessageLength(uid);// notice.size();
                returnMap.put("code", 1);
                returnMap.put("errmsg", "ok");
                returnMap.put("total", length);
                returnMap.put("pagenum", jsonArray.size());
                returnMap.put("eachpage", 10);
                returnMap.put("notice", jsonArray);
                // 返回给小程序
                return returnMap;
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("noticelsit error:" + uid + " " + from+e.getMessage());
                returnMap.put("code", 0);
                returnMap.put("msg", "网络异常");
                return returnMap;
            }
        }
        // 来自首页的更新请求
        else if (!from.equals("1") && flag) {
            try {
                JSONArray jsonArray = weixinService.getMessage(uid, 1, 10);
                returnMap.put("code", 1);
                returnMap.put("msg", "ok");
                returnMap.put("notice", jsonArray);
                returnMap.put("total", jsonArray.size());
                // 返回给小程序
                return returnMap;
            } catch (Exception e) {
                logger.error("noticelsit error:" + uid + " " + from+e.getMessage());
                returnMap.put("code", 0);
                returnMap.put("msg", "网络异常");
                return returnMap;
            }
        }
        return null;
    }
    @ApiOperation(value = "获取消息列表的翻页")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "用户ID",value = "uid",paramType = "query",dataType = "String",required = true),
            @ApiImplicitParam(name = "页码",value = "page",paramType = "query",dataType = "int",required = true)
    })
    @RequestMapping(value = "noticenewpage",method = RequestMethod.GET)
    public Map<String,Object> noticeListNewPage(String uid,int page){
        Map<String,Object> returnMap = new HashMap<>();
        // 表示来自消息列表
        try {
            JSONArray jsonArray = weixinService.getMessage(uid, page, 10);
            int length = jsonArray.size();
            returnMap.put("code", 1);
            returnMap.put("msg", "ok");
            returnMap.put("pagenum", length);
            returnMap.put("notice", jsonArray);
            // 返回给小程序
            return returnMap;
        } catch (Exception e) {
            logger.error("noticeLstNewPage error:" + uid + " " + page+e.getMessage());
            returnMap.put("code", 0);
            returnMap.put("msg", "网络异常");
            return returnMap;
        }
    }


    // 获取用户微信信息
    private String getWeixinUserData(String code, String appid, String secret) {
        String stringToken = String.format(
                "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                appid, secret, code);
        String response = HttpUtils.httpsRequestToString(stringToken, "GET", null);
        return response;
    }
}
